package com.bjtu.ptsite.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bjtu.ptsite.mapper.SeedingRecordMapper;
import com.bjtu.ptsite.mapper.TorrentCommentMapper;
import com.bjtu.ptsite.mapper.UserMapper;
import com.bjtu.ptsite.model.SeedingRecord;
import com.bjtu.ptsite.model.TorrentComment;
import com.bjtu.ptsite.model.TorrentCommentRequest;
import com.bjtu.ptsite.model.User;
import com.bjtu.ptsite.service.SeedingService;
import com.bjtu.ptsite.tracker.entity.TrackerMessage;
import com.bjtu.ptsite.mapper.TrackerMessageMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 * @author Zehao Wang, Junjie Zhang, Yutao Wei
 *
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class SeedingServiceImpl implements SeedingService {
    private final SeedingRecordMapper seedingRecordMapper;
    private final UserMapper userMapper;
    private final TrackerMessageMapper seedMapper;

    private final TorrentCommentMapper torrentCommentMapper;

    @Autowired
    public SeedingServiceImpl(SeedingRecordMapper seedingRecordMapper, UserMapper userMapper,
                              TrackerMessageMapper seedMapper, TorrentCommentMapper torrentCommentMapper) {
        this.seedingRecordMapper = seedingRecordMapper;
        this.userMapper = userMapper;
        this.seedMapper = seedMapper;
        this.torrentCommentMapper = torrentCommentMapper;
    }

    public void updateSeedingStatus(Long seedId, int userId) {
        QueryWrapper<SeedingRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("seed_id", seedId).eq("user_id", userId);
        SeedingRecord record = seedingRecordMapper.selectOne(wrapper);
        TrackerMessage trackerMessage = seedMapper.selectById(Math.toIntExact(seedId));

        if (record == null) {
            record = new SeedingRecord();
            record.setSeedId(seedId);
            record.setUserId(userId);
            record.setStartTime(LocalDateTime.now());
            seedingRecordMapper.insert(record);
        }

        LocalDateTime now = LocalDateTime.now();
        if (record.getStartTime() == null) {
            record.setStartTime(now);
        }
        record.setLastReportTime(now);
        seedingRecordMapper.updateById(record);

        // 计算积分
        long hours = Duration.between(record.getStartTime(), now).toHours();
        User user = userMapper.selectById(userId);
        if (user != null) {
            user.setSeedPoints((int) (user.getSeedPoints() + hours * 10 * trackerMessage.getUploadMultiplier()));
            userMapper.updateUserSelective(user);
        }
    }

    @Override
    public void comment(TorrentCommentRequest torrentCommentRequest) {
        try {
            TorrentComment build = TorrentComment.builder()
                    .torrentId(torrentCommentRequest.getTorrentId())
                    .userId(torrentCommentRequest.getUserId())
                    .content(torrentCommentRequest.getContent())
                    .isAnonymous(torrentCommentRequest.getIsAnonymous())
                    .createdAt(LocalDateTime.now())
                    .build();

            torrentCommentMapper.insert(build);
        } catch (Exception e) {
            log.error("comment error :{}",e.getMessage());
        }

    }

    @Override
    public PageInfo<TorrentComment> getCommentList(TorrentCommentRequest req) {
        PageInfo<TorrentComment> pageInfo = null;
        try {
            PageHelper.startPage(req.getPage(), req.getSize());
            List<TorrentComment> torrentComments = torrentCommentMapper.getCommentList(req.getTorrentId());
            torrentComments.stream().map(torrentComment -> {
                if(torrentCommentMapper.likeExist(torrentComment.getUserId(), torrentComment.getId())){
                    torrentComment.setIsLike(true);
                }
                else{
                    torrentComment.setIsLike(false);
                }
                return torrentComment;
            }).collect(Collectors.toList());
            pageInfo = new PageInfo<>(torrentComments);
        } catch (Exception e) {
              log.info("分页查询失败:{}",e.getMessage(),e);
        }

        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void likes(TorrentCommentRequest torrentCommentRequest) {
        Long id = torrentCommentRequest.getId();
        Long userId=torrentCommentRequest.getUserId();
        //数据库增加，后续可redis计数优化，估计没后续了
        torrentCommentMapper.incrrementLikes(id);
        torrentCommentMapper.createLike(userId,id);
    }

    @Override
    public void deleteComment(TorrentCommentRequest torrentCommentRequest) {
        Long id = torrentCommentRequest.getId();
        //数据库删除,物理删，非逻辑
        torrentCommentMapper.deleteById(id);
    }

    @Override
    public boolean likeExist(Long userId,Long id){
        return torrentCommentMapper.likeExist(userId, id);
    } 

    @Override
    public TorrentComment selectById(Long id){
        return torrentCommentMapper.selectById(id);
    }
}